package com.jdd.modules.parking.controller;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.andyczy.java.excel.ExcelUtils;
import com.jdd.common.api.vo.Result;
import com.jdd.common.aspect.annotation.*;
import com.jdd.common.constant.JddConstant;
import com.jdd.common.system.query.QueryGenerator;
import com.jdd.common.system.vo.LoginUser;
import com.jdd.common.util.*;
import com.jdd.common.util.excel.entity.params.ExportParams;
import com.jdd.common.util.excel.entity.params.ImportParams;
import com.jdd.common.util.excel.util.ExcelImportUtil;
import com.jdd.common.util.excel.web.entity.vo.NormalExcelConstants;
import com.jdd.common.util.excel.web.view.EasypoiSingleExcelView;
import com.jdd.modules.area.entity.ParkAreaInfo;
import com.jdd.modules.area.service.IParkAreaInfoService;
import com.jdd.modules.configcartype.entity.ConfigCarType;
import com.jdd.modules.configcartype.service.IConfigCarTypeService;
import com.jdd.modules.parkcar.entity.*;
import com.jdd.modules.parking.entity.*;
import com.jdd.modules.parking.mapper.ParkCarEnterLogMapper;
import com.jdd.modules.parking.service.IConfigParkInfoService;
import com.jdd.modules.parking.service.IparkCarEnterLogService;
import com.jdd.modules.parking.service.impl.ParkArmInfoServiceImpl;
import com.jdd.modules.parking.vo.MontiorSearchRespVo;
import com.jdd.modules.parking.vo.MontiorSearchVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;

/**
 * @Description: 车辆入场信息
 * @Author: jdd
 * @Date: 2021-02-20
 * @Version: V1.0m
 */
@Slf4j
@Api(tags = "车辆入场信息")
@RestController
@RequestMapping("/parking/parkCarEnterLog")
public class ParkCarEnterLogController {

    @Resource
    private IparkCarEnterLogService parkCarEnterLogService;
    @Resource
    private IConfigCarTypeService configCarTypeService;
    @Resource
    private IParkAreaInfoService parkAreaInfoService;
    @Resource
    private IConfigParkInfoService configParkInfoService;

    @Resource
    private ParkArmInfoServiceImpl parkArmInfoService;
    @Resource
    ParkCarEnterLogMapper parkCarEnterLogMapper;


    /**
     * 分页列表查询
     *
     * @param parkCarEnterLog
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @AutoLog(value = "车辆入场信息-分页列表查询")
    @ApiOperation(value = "车辆入场信息-分页列表查询", notes = "车辆入场信息-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<ParkCarEnterLog>> queryPageList(ParkCarEnterLog parkCarEnterLog,
                                                        @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                        @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                        HttpServletRequest req) {
        Result<IPage<ParkCarEnterLog>> result = new Result<IPage<ParkCarEnterLog>>();
        QueryWrapper<ParkCarEnterLog> queryWrapper = new QueryWrapper<>();
        if(ObjectUtil.isNotEmpty(parkCarEnterLog)){
            if(ObjectUtil.isNotEmpty(parkCarEnterLog.getPlateNo())){
                queryWrapper.like("plate_no",parkCarEnterLog.getPlateNo());
            }
            if(ObjectUtil.isNotEmpty(parkCarEnterLog.getCarType())){
                queryWrapper.eq("car_type",parkCarEnterLog.getCarType());
            }
            if(ObjectUtil.isNotEmpty(parkCarEnterLog.getCarNature())){
                queryWrapper.eq("car_nature",parkCarEnterLog.getCarNature());
            }
        }
        String createTime_begin = req.getParameter("createTime_begin");
        String createTime_end = req.getParameter("createTime_end");
        if(ObjectUtil.isNotEmpty(createTime_begin)){
            queryWrapper.ge("car_enter_time",createTime_begin);
        }
        if(ObjectUtil.isNotEmpty(createTime_end)){
            queryWrapper.le("car_enter_time",createTime_end);
        }
        queryWrapper.ne("is_transfer", JddConstant.StringNumber.STRING_ONE);
        queryWrapper.lambda().orderByDesc(ParkCarEnterLog::getCreateTime);
        Page<ParkCarEnterLog> page = new Page<ParkCarEnterLog>(pageNo, pageSize);
        IPage<ParkCarEnterLog> pageList = parkCarEnterLogService.page(page, queryWrapper);
        result.setSuccess(true);
        result.setResult(pageList);
        return result;
    }

    @ApiOperation(value = "监控页面车辆入场信息-分页列表查询", notes = "监控页面车辆入场信息-分页列表查询")
    @GetMapping(value = "/monitorList")
    public Result<Page<MontiorSearchRespVo>> monitorList(MontiorSearchVo montiorSearchVo,
                                                        @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                        @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize){
        Result<Page<MontiorSearchRespVo>> result = new Result<>();
        try {
            //入场纪录日志，已出场得也会算进去
            Page<MontiorSearchRespVo> page = parkCarEnterLogService.monitorList(montiorSearchVo, pageNo, pageSize);
            result.setResult(page);
            result.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            result.error500("系统异常");
        }
        return result;
    }

    /**
     * 添加
     *
     * @param parkCarEnterLog
     * @return
     */
    @AutoLog(value = "车辆入场信息-添加")
    @ApiOperation(value = "车辆入场信息-添加", notes = "车辆入场信息-添加")
    @PostMapping(value = "/add")
    @OperationLogDetail(detail = "车辆入场信息，添加", level = LogLevelType.ONE, operationType = OperationType.INSERT, operationUnit = OperationUnit.UNKNOWN)
    public Result<ParkCarEnterLog> add(@RequestBody ParkCarEnterLog parkCarEnterLog) {
        Result<ParkCarEnterLog> result = new Result<ParkCarEnterLog>();
        try {
            parkCarEnterLog.setId(SnowFlakeUtil.getId());
            parkCarEnterLogService.save(parkCarEnterLog);
            result.success("添加成功！");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.error500("操作失败");
        }
        return result;
    }

    /**
     * 编辑
     *
     * @param parkCarEnterLog
     * @return
     */
    @AutoLog(value = "车辆入场信息-编辑")
    @ApiOperation(value = "车辆入场信息-编辑", notes = "车辆入场信息-编辑")
    @PutMapping(value = "/edit")
    @OperationLogDetail(detail = "车辆入场信息，编辑", level = LogLevelType.ONE, operationType = OperationType.UPDATE, operationUnit = OperationUnit.UNKNOWN)
    public Result<ParkCarEnterLog> edit(@RequestBody ParkCarEnterLog parkCarEnterLog) {
        Result<ParkCarEnterLog> result = new Result<ParkCarEnterLog>();
        ParkCarEnterLog parkCarEnterLogEntity = parkCarEnterLogService.getById(parkCarEnterLog.getId());
        if (parkCarEnterLogEntity == null) {
            result.error500("未找到对应实体");
        } else {
            boolean ok = parkCarEnterLogService.updateById(parkCarEnterLog);
            //TODO 返回false说明什么？
            if (ok) {
                result.success("修改成功!");
            }
        }

        return result;
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "车辆入场信息-通过id删除")
    @ApiOperation(value = "车辆入场信息-通过id删除", notes = "车辆入场信息-通过id删除")
    @DeleteMapping(value = "/delete")
    @OperationLogDetail(detail = "车辆入场信息，通过id删除", level = LogLevelType.ONE, operationType = OperationType.DELETE, operationUnit = OperationUnit.UNKNOWN)
    public Result<?> delete(@RequestParam(name = "invateuserdetailId", required = true) String id) {
        try {
            parkCarEnterLogService.removeById(id);
        } catch (Exception e) {
            log.error("删除失败", e.getMessage());
            return Result.error("删除失败!");
        }
        return Result.ok("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "车辆入场信息-批量删除")
    @ApiOperation(value = "车辆入场信息-批量删除", notes = "车辆入场信息-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    @OperationLogDetail(detail = "车辆入场信息，批量删除", level = LogLevelType.ONE, operationType = OperationType.DELETE, operationUnit = OperationUnit.UNKNOWN)
    public Result<ParkCarEnterLog> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        Result<ParkCarEnterLog> result = new Result<ParkCarEnterLog>();
        if (ids == null || "".equals(ids.trim())) {
            result.error500("参数不识别！");
        } else {
            this.parkCarEnterLogService.removeByIds(Arrays.asList(ids.split(",")));
            result.success("删除成功!");
        }
        return result;
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "车辆入场信息-通过id查询")
    @ApiOperation(value = "车辆入场信息-通过id查询", notes = "车辆入场信息-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<ParkCarEnterLog> queryById(@RequestParam(name = "id", required = true) String id) {
        Result<ParkCarEnterLog> result = new Result<ParkCarEnterLog>();
        ParkCarEnterLog parkCarEnterLog = parkCarEnterLogService.getById(id);
        if (parkCarEnterLog == null) {
            result.error500("未找到对应实体");
        } else {
            result.setResult(parkCarEnterLog);
            result.setSuccess(true);
        }
        return result;
    }

    /**
     * 导出excel
     *
     * @param request
     * @param response
     * @Author liushengnan（修改：加入翻译)
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response, ParkCarEnterLog parkCarEnterLog) {

        QueryWrapper<ParkCarEnterLog> queryWrapper = QueryGenerator.initQueryWrapper(parkCarEnterLog, request.getParameterMap());
        ModelAndView mv = null;
        List<ParkCarEnterLog> pageList = parkCarEnterLogService.list(queryWrapper);
        if (pageList.size() != 0) {
            mv = new ModelAndView(new EasypoiSingleExcelView());
            for (ParkCarEnterLog parkCarEnterLog1 : pageList) {
                if ("0".equals(parkCarEnterLog1.getCarNature())) {
                    parkCarEnterLog1.setCarNature("临时车");
                } else if ("1".equals(parkCarEnterLog1.getCarNature())) {
                    parkCarEnterLog1.setCarNature("月租车");
                } else if ("2".equals(parkCarEnterLog1.getCarNature())) {
                    parkCarEnterLog1.setCarNature("军警医车");
                }
                if ("0".equals(parkCarEnterLog1.getCarType())) {
                    parkCarEnterLog1.setCarType("无牌车");
                } else if ("1".equals(parkCarEnterLog1.getCarType())) {
                    parkCarEnterLog1.setCarType("有牌车");
                }
                if ("0".equals(parkCarEnterLog1.getIsOut())) {
                    parkCarEnterLog1.setIsOut("未出场");
                } else {
                    parkCarEnterLog1.setIsOut("已出场");

                }
            }
            mv.addObject(NormalExcelConstants.FILE_NAME, "车辆入场记录");
            mv.addObject(NormalExcelConstants.CLASS, ParkCarEnterLog.class);
            mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("车辆入场记录", "车辆入场记录导出信息"));
            mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
        }
        return mv;
    }


    /**
     * 根据车辆编号、车牌类型匹配停车场的车辆类型Id
     *
     * @param type 车牌类型
     * @return java.lang.String
     * @version 1.0
     */
    private String getCarType(int type) {
        String result = null;
        List<ConfigCarType> list = configCarTypeService.getCarTypeList();
        for (ConfigCarType carType : list) {
            String carTypeName = carType.getCarTypeName();
            List<String> typeNo = Arrays.asList(carType.getCarTypeNo().split(","));
            if (typeNo.contains(type + "")) {
                result = carTypeName;
                return result;
            }
        }
        return result;
    }

    /**
     * @param request
     * @param response
     * @param map
     * @return 导入结果
     */
    @AutoLog(value = "车辆入场信息-导出车辆入场信息模板")
    @ApiOperation(value = "车辆入场信息-导出车辆入场信息模板", notes = "车辆入场信息-导出车辆入场信息模板")
    @RequestMapping(value = "/importTemplate")
    public ModelAndView exportXlsTemplate(HttpServletRequest request, HttpServletResponse response, Map<String, Object> map) {

        ModelAndView mv = new ModelAndView(new EasypoiSingleExcelView());
        mv.addObject(NormalExcelConstants.FILE_NAME, "车辆入场信息");
        mv.addObject(NormalExcelConstants.CLASS, ParkCarEnterLogImport.class);
        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("车辆入场信息", "车辆入场信息模板"));
//32
        ParkCarEnterLogImport parkCarEnterLogImport = new ParkCarEnterLogImport(null,null,null,null,null);

        //StoreCar storeCar = new StoreCar(null, null, null, null, null, null, null);
        List<ParkCarEnterLogImport> list = new LinkedList<>();
        list.add(parkCarEnterLogImport);
        mv.addObject(NormalExcelConstants.DATA_LIST, list);
        return mv;
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @return 导入结果Excel
     */
    @AutoLog(value = "车辆入场信息-导入车辆入场信息")
    @ApiOperation(value = "车辆入场信息-导入车辆入场信息", notes = "车辆入场信息-导入车辆入场信息")
    @RequestMapping(value = "/importExcel")
    public Result<List<ParkCarEnterLogImportResult>> importExcel(HttpServletRequest request, HttpServletResponse response) throws IOException {
        log.info("----车辆入场信息导入----");
        Result<List<ParkCarEnterLogImportResult>> result = new Result<>();
        //导入结果信息列表
        List<ParkCarEnterLogImportResult> importResultMessageList = new LinkedList<>();
        //用于存储的格式正确的车辆入场信息
        List<ParkCarEnterLog> parkCarEnterLogList = new ArrayList<>();
        //用于存储拥有相同数据的车辆入场信息
        List<ParkCarEnterLog> sameParkCarEnterLogList = new ArrayList<>();

        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        //导入方式 1:忽略重复(以已存在记录为准) 0:覆盖导入(以最新记录为准)
        String importType = multipartRequest.getParameter("importType");
        // 从请求中获得上传文件的集合
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            try {
                // 获得文件
                MultipartFile file = entity.getValue();
                // 得到文件名
                String fileName = file.getOriginalFilename();
                // 获得Excel文件的扩展名
                String extName = fileName.substring(fileName.lastIndexOf('.') + 1);
                //获取Excel数据
                List<List<LinkedHashMap<String, String>>> excelLists = getExcelLists(file, extName);
                //数据校验组装
                for (List<LinkedHashMap<String, String>> linkedHashMaps : excelLists) {
                    getNoSameDataParkCarBlack(request, linkedHashMaps, parkCarEnterLogList, sameParkCarEnterLogList, false);
                }
                //数据导入
                importResultMessageList = importParkCarEnterLogByList(request, parkCarEnterLogList, importType);
                if (importResultMessageList.size() > 0) {
                    result.setResult(importResultMessageList);
                    result.setSuccess(false);
                    return result;
                }

            }catch (Exception e) {
                log.error("车辆入场信息导入失败", e);
                result.error500("车辆入场信息导入失败");
                return result;
            }
        }
        result.success("车辆入场信息导入成功！");
        ParkCarEnterLogImportResult parkCarEnterLogImportResult = new ParkCarEnterLogImportResult();
        parkCarEnterLogImportResult.setTotalCount(parkCarEnterLogList.size());
        importResultMessageList.add(parkCarEnterLogImportResult);
        result.setResult(importResultMessageList);
        result.setSuccess(true);

        return result;
    }

    /**
     * 按list批量导入
     *
     * @param request    request
     * @param list       格式正确的储值车信息
     * @param importType 导入方式 1:忽略重复(以已存在记录为准) 0:覆盖导入(以最新记录为准)
     * @return 导入结果信息
     */
    private List<ParkCarEnterLogImportResult> importParkCarEnterLogByList(HttpServletRequest request, List<ParkCarEnterLog> list, String importType) {
        List<ParkCarEnterLogImportResult> importResultMessageList = new ArrayList<>();
        String currDateTime = request.getParameter("currDateTime");

        for (int i = 0; i < list.size(); i++) {
            ParkCarEnterLog parkCarEnterLog = list.get(i);
            try {
                // 创建一个数值格式化对象
                NumberFormat numberFormat = NumberFormat.getInstance();
                numberFormat.setMaximumFractionDigits(0);
                String result = numberFormat.format((float) i / (float) list.size() * 100);
                request.getSession().setAttribute(currDateTime, Integer.parseInt(result));
                LambdaQueryWrapper<ParkCarEnterLog> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(ParkCarEnterLog::getPlateNo, parkCarEnterLog.getPlateNo());
                queryWrapper.orderByAsc(true);


                List<ParkCarEnterLog> existParkInfoList = parkCarEnterLogService.list(queryWrapper);



                if (null != existParkInfoList) {
                    //忽略重复(以已存在记录为准)
                    if (JddConstant.StringNumber.STRING_ZERO.equals(importType)) {
                        parkCarEnterLogService.save(parkCarEnterLog);
                        continue;
                    } else {
                        //覆盖导入(以最新记录为准)
                        parkCarEnterLogMapper.updateIsOut(parkCarEnterLog.getPlateNo());
                        parkCarEnterLogService.save(parkCarEnterLog);
                        continue;
                    }
                }
                parkCarEnterLogService.save(parkCarEnterLog);
            } catch (Exception e) {
                ParkCarEnterLogImportResult message = new ParkCarEnterLogImportResult();
                message.setTotalCount(list.size());
                message.setId(i + 3);
                message.setPlateNo(parkCarEnterLog.getPlateNo());
                message.setMessage("导入失败" + e.getMessage());
                message.setStatus("失败");
                importResultMessageList.add(message);
            }
        }
        return importResultMessageList;
    }




    /**
     * 车辆入场信息通过excel导入数据校验
     *
     * @param request  request
     * @param response response
     * @return 数据校验结果
     */
    @RequestMapping(value = "/importFromExcelCheck", method = RequestMethod.POST)
    public Result<List<ParkCarEnterLogImportResult>> importFromExcelCheck(HttpServletRequest request, HttpServletResponse response) {
        Result<List<ParkCarEnterLogImportResult>> result = new Result<>();
        //校验结果信息列表
        List<ParkCarEnterLogImportResult> importResultMessageList = new LinkedList<>();
        //用于存储的格式正确的车辆入场信息
        List<ParkCarEnterLog> parkCarEnterLogList = new ArrayList<>();
        //用于存储拥有相同数据的车辆入场信息
        List<ParkCarEnterLog> sameParkCarEnterLogList = new ArrayList<>();

        // 获得上传文件的请求
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        String importType = multipartRequest.getParameter("importType");
        // 从请求中获得上传文件的集合
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        // 遍历文件集合
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            try {
                // 获得文件
                MultipartFile file = entity.getValue();
                // 得到文件名
                String fileName = file.getOriginalFilename();
                // 获得Excel文件的扩展名
                String extName = fileName.substring(fileName.lastIndexOf('.') + 1);
                //excel文件格式校验
                if (!StringUtils.equals("xls", extName) && !StringUtils.equals("xlsx", extName)) {
                    log.error("无法识别的Excel文件,请下载模板文件,进行导入!");
                    result.error500("无法识别的Excel文件,请下载模板文件,进行导入");
                    return result;
                }

                //获取Excel数据
                List<List<LinkedHashMap<String, String>>> excelLists = getExcelLists(file, extName);

                //检测导入Excel文件的大小
                Result<Object> listSizeCheckResult = importListSizeCheck(excelLists, 1000);
                //如果检测不通过
                if (listSizeCheckResult.getCode() != 200) {
                    log.error(listSizeCheckResult.getMessage());
                    result.error500(listSizeCheckResult.getMessage());
                    return result;
                }

                //数据校验组装
                for (List<LinkedHashMap<String, String>> linkedHashMaps : excelLists) {
                    importResultMessageList = getNoSameDataParkCarBlack(request, linkedHashMaps, parkCarEnterLogList, sameParkCarEnterLogList, true);

                }
                if (importResultMessageList.size() > 0) {
                    result.setResult(importResultMessageList);
                    result.setSuccess(false);
                    return result;
                }

            } catch (Exception e) {
                log.error("车辆入场信息文件校验失败", e);
                result.error500("车辆入场信息文件校验失败");
                return result;
            }
        }
        result.success("车辆入场信息文件校验成功！");

        ParkCarEnterLogImportResult parkCarEnterLogImportResult = new ParkCarEnterLogImportResult();
        parkCarEnterLogImportResult.setTotalCount(parkCarEnterLogList.size());
        importResultMessageList.add(parkCarEnterLogImportResult);
        result.setResult(importResultMessageList);
        result.setSuccess(true);
        return result;
    }

    /**
     * Excel列表中数据格式自检测
     *
     * @param request        request
     * @param linkedHashMaps 导入的车辆入场信息列表
     * @param noSameDataList 用于存储的格式正确的，无相同数据的储值车信息
     * @param sameDatalist   用于存储拥有相同数据的储值车信息
     * @param isCheck        是否为校验操作
     * @return 导入结果信息
     */
    private List<ParkCarEnterLogImportResult> getNoSameDataParkCarBlack(HttpServletRequest request, List<LinkedHashMap<String, String>> linkedHashMaps, List<ParkCarEnterLog> noSameDataList,
                                                                        List<ParkCarEnterLog> sameDatalist, boolean isCheck) {
        LoginUser loginUser = LoginUserUtils.getLoginUser();
        List<ParkCarEnterLogImportResult> resultList = new ArrayList<>();
        Set<String> noSameDataPlantNoList = new HashSet<>();

        ConfigParkInfo configParkInfo = configParkInfoService.findConfigParkInfoByParkCode();
        String currDateTime = request.getParameter("currDateTime");

        for (int index = 0; index < linkedHashMaps.size(); index++) {
            if (isCheck) {
                // 创建一个数值格式化对象
                NumberFormat numberFormat = NumberFormat.getInstance();
                numberFormat.setMaximumFractionDigits(0);
                String result = numberFormat.format((float) index / (float) linkedHashMaps.size() * 100);
                request.getSession().setAttribute(currDateTime, Integer.parseInt(result));
            }

            ParkCarEnterLog parkCarEnterLog = new ParkCarEnterLog();
            LinkedHashMap<String, String> linkedHashMap = linkedHashMaps.get(index);

            /*{0=豫LSC002, 1=2022-05-06 12:04:40, 2=9483b619-42d6b87b222, 3=有牌车, 4=备注1}*/
            String plateNo = linkedHashMap.get("0");
            String carEnterTime = linkedHashMap.get("1");
            String serialNo = linkedHashMap.get("2");
            String carTypeName = linkedHashMap.get("3");
            String remark = linkedHashMap.get("4");


            ParkCarEnterLogImportResult message = new ParkCarEnterLogImportResult();
            message.setTotalCount(linkedHashMaps.size());
            message.setId(index + 3);
            message.setPlateNo(plateNo);
            message.setStatus("失败");

            //车牌号检查
            if (StringUtils.isBlank(plateNo) || !PlateNoCheckUtil.checkPlateNo(plateNo)) {
                // 如果车辆的车牌号为空或错误的格式，放弃此数据，立即开始导入一下条数据
                log.error("车牌号格式错误");
                message.setMessage("车牌号格式错误");
                resultList.add(message);
                continue;
            } else {
                parkCarEnterLog.setPlateNo(plateNo);
            }
            //车辆进场时间检查
            if (dateTimeCheck(carEnterTime, "yyyy-MM-dd HH:mm:ss")) {
                parkCarEnterLog.setCarEnterTime(carEnterTime);
            } else {
                log.error("车辆进场时间格式错误");
                message.setMessage("车辆进场时间格式错误");
                resultList.add(message);
                continue;
            }
            //设备序列号检查
            ParkArmInfo parkArmInfo = serialNoCheck(serialNo);
            if (StringUtils.isBlank(serialNo) || parkArmInfo == null){
                log.error("设备序列号错误");
                message.setMessage("设备序列号错误");
                resultList.add(message);
                continue;
            }else{
                parkCarEnterLog.setSerialNo(serialNo);
                parkCarEnterLog.setArmName(parkArmInfo.getArmName());
                parkCarEnterLog.setIpAddr(parkArmInfo.getIpAddr());
            }

            //车辆类型检查
            ConfigCarType configCarType = carTypeCheck(carTypeName);
            if (StringUtils.isBlank(carTypeName) || configCarType == null){
                log.error("车辆类型错误");
                message.setMessage("车辆类型错误");
                resultList.add(message);
                continue;
            }else {
                parkCarEnterLog.setCarTypeName(carTypeName);
                parkCarEnterLog.setCarNature(configCarType.getCarType());
                parkCarEnterLog.setCarTypeId(configCarType.getId());
                if (StringUtils.equals(carTypeName,"临时车A")){
                    parkCarEnterLog.setCarTypeNo("1");
                }else if (StringUtils.equals(carTypeName,"临时车B")){
                    parkCarEnterLog.setCarTypeNo("3");
                }else {
                    parkCarEnterLog.setCarTypeNo("1");
                }
            }
            //备注检查
            if (StringUtils.isEmpty(remark) || remark.length() <= 100) {
                parkCarEnterLog.setRemark(remark);
            } else {
                log.error("车辆入场信息备注长度不要超过100个字符");
                message.setMessage("车辆入场信息备注长度不要超过100个字符");
                resultList.add(message);
                continue;
            }
            parkCarEnterLog.setId(SnowFlakeUtil.getId());
            parkCarEnterLog.setBatchNumber(parkCarEnterLog.getId());
            parkCarEnterLog.setParkCode(configParkInfo.getParkCode());
            parkCarEnterLog.setParkName(configParkInfo.getParkName());
            parkCarEnterLog.setAreaId(parkArmInfo.getTargetAreaId());
            parkCarEnterLog.setCarType("1");
            parkCarEnterLog.setIsOut("0");


            parkCarEnterLog.setCreateTime(new Date());    //不覆盖 则不管 覆盖则是更新时间
            parkCarEnterLog.setUpdateTime(new Date());

            parkCarEnterLog.setOpenid("1");
            parkCarEnterLog.setSynchronousStatus("N");
            parkCarEnterLog.setIsTransfer("0");
            parkCarEnterLog.setEnterType(4);
            if (noSameDataPlantNoList.add(parkCarEnterLog.getPlateNo())) {
                noSameDataList.add(parkCarEnterLog);
            } else {
                message.setMessage("导入文件中已存在一条相同车牌号的数据，请勿重复导入");
                resultList.add(message);
                sameDatalist.add(parkCarEnterLog);
            }
        }
        return resultList;
    }

    /**
     * @return 返回当前用户所在车场的所有区域列表
     */
    @AutoLog(value = "车辆入场信息-获取车场配置信息")
    @ApiOperation(value = "车辆入场信息-获取车场配置信息", notes = "车辆入场信息-获取车场配置信息")
    @GetMapping(value = "/findConfigParkInfo")
    public Result<?> findConfigParkInfo(HttpServletRequest request) {
        request.getSession();
        ConfigParkInfo configParkInfo = configParkInfoService.findConfigParkInfoByParkCode();
        if (ObjectUtil.isNull(configParkInfo)) {
            return Result.error("获取车场配置信息失败！");
        } else {
            return Result.ok(configParkInfo);
        }
    }

    /**
     * 获取Excel数据
     *
     * @param file    文件
     * @param extName 文件扩展名
     * @return 列表数据
     * @throws IOException 异常信息
     */
    private List<List<LinkedHashMap<String, String>>> getExcelLists(MultipartFile file, String extName) throws IOException {
        // 设置Excel文件的标题所在行数
        HashMap<Integer, Integer> hashMapIndex = new HashMap<>(1);
        hashMapIndex.put(1, 3);
        // 设置Excel文件单页名称
        String[] sheetNames = new String[]{"车辆入场信息"};
        // 获得Excel文件的输入流
        InputStream inputStream = file.getInputStream();
        Workbook book = null;

        if (StringUtils.equals("xls", extName)) {
            // Excel文件为Excel2003之前的版本
            book = new HSSFWorkbook(inputStream);
        } else if (StringUtils.equals("xlsx", extName)) {
            // Excel文件的版本为Excel2007
            book = new XSSFWorkbook(inputStream);
        }
        // 初始化Excel工具类
        ExcelUtils excelUtils = ExcelUtils.initialization();
        // 设置工具类读取日期数据的格式
        excelUtils.setDateFormatStr("yyyy-MM-dd HH:mm:ss");
        excelUtils.setExpectDateFormatStr("yyyy-MM-dd HH:mm:ss");
        // 读取Excel文件
        List<List<LinkedHashMap<String, String>>> list = ExcelUtils.importForExcelData(book, sheetNames, hashMapIndex, null);
        return list;
    }
    /**
     * 校验时间格式
     *
     * @param inputDateTime 时间字符串
     * @param format        时间格式
     * @return 校验结果
     */
    private boolean dateTimeCheck(String inputDateTime, String format) {
        SimpleDateFormat sdfDay = new SimpleDateFormat(format);
        sdfDay.setLenient(false);
        if (org.apache.commons.lang.StringUtils.isEmpty(inputDateTime)) {
            return false;
        }
        try {
            Date date = sdfDay.parse(inputDateTime);
            return inputDateTime.equals(sdfDay.format(date));
        } catch (ParseException e) {
            return false;
        }
    }
    /**
     * 校验车辆类型是否属于储值车和临时车
     *
     * @param carTypeName 车辆类型名
     * @return 校验结果
     */
    public ConfigCarType carTypeCheck(String carTypeName) {
        ConfigParkInfo configParkInfo = configParkInfoService.findConfigParkInfoByParkCode();
        String parkCode = configParkInfo.getParkCode();
        QueryWrapper<ConfigCarType> wrapper = new QueryWrapper();
        wrapper.eq("park_code",parkCode);
        wrapper.eq("car_type","0").or().eq("car_type","2");

        List<ConfigCarType> list = configCarTypeService.list(wrapper);
        for (ConfigCarType configCarType:list){
            if (StringUtils.equals(configCarType.getCarTypeName(),carTypeName)){
                return configCarType;
            }
        }
        return null;
    }

    /**
     * 校验设备序列号是否存在
     *
     * @param serialNo 设备序列号
     * @return 校验结果
     */
    private ParkArmInfo serialNoCheck(String serialNo) {
        ConfigParkInfo configParkInfo = configParkInfoService.findConfigParkInfoByParkCode();
        String parkCode = configParkInfo.getParkCode();
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("park_code",parkCode);
        wrapper.eq("arm_type",JddConstant.StringNumber.STRING_ZERO);
        List<ParkArmInfo> list = parkArmInfoService.list(wrapper);
        for (ParkArmInfo parkArmInfo:list){
            if (StringUtils.equals(parkArmInfo.getSerialNo(),serialNo)){
                return parkArmInfo;
            }
        }
        return null;
    }

    /**
     * 车辆入场信息校验及导入进度获取
     *
     * @param request  request
     * @param response response
     * @return 进度数据
     */
    @RequestMapping(value = "/getCheckProgress", method = RequestMethod.POST)
    public Result<Integer> getCheckProgress(HttpServletRequest request, HttpServletResponse response) {
        Result<Integer> result = new Result<>();
        String currDateTime = request.getParameter("currDateTime");
        try {
            String percent = String.valueOf(request.getSession().getAttribute(currDateTime));
            if (StringUtils.isEmpty(percent) || "null".equals(percent)) {
                percent = "0";
            }
            result.setResult(Integer.parseInt(percent));
        } catch (Exception e) {
            result.setResult(0);
        }
        return result;
    }

    /**
     * 检测车辆入场信息导入列表的大小
     */
    private Result<Object> importListSizeCheck(List<List<LinkedHashMap<String, String>>> list, Integer maxSize) {

        // 如果列表大小不为0
        if (list.size() != 0) {
            if (list.get(0).size() > maxSize) {
                log.error("表格中的数据最多有" + maxSize + "条");
                return Result.error("表格中的数据最多有" + maxSize + "条");
            }
            if (list.get(0).size() != 0) {
                String[] arr = new String[list.get(0).get(0).size()];
                Arrays.fill(arr, "");
                String[] arr1 = new String[list.get(0).get(0).size()];
                String[] strings = list.get(0).get(0).values().toArray(arr1);
                if (Arrays.equals(arr, strings)) {
                    log.error("文件没有数据");
                    return Result.error("文件没有数据！");
                }
            }
        } else {
            log.error("空文件");
            return Result.error("空文件");
        }
        return Result.ok();
    }

}


